package com.gengzp.system.service.impl;

import com.gengzp.common.enums.PermissionEnum;
import com.gengzp.common.exception.BusinessException;
import com.gengzp.common.model.pagination.resp.PaginationResult;
import com.gengzp.common.model.permission.dto.PermissionDto;
import com.gengzp.common.model.role.entity.SysRole;
import com.gengzp.common.model.role.req.AddSysRoleReq;
import com.gengzp.common.model.role.req.EditSysRoleReq;
import com.gengzp.common.model.role.req.PageSysRoleReq;
import com.gengzp.common.model.role.resp.PageSysRoleResp;
import com.gengzp.common.model.role.resp.SearchSysRolePermissionsResp;
import com.gengzp.common.model.role.resp.SearchSysRoleResp;
import com.gengzp.common.utils.ExecutorUtils;
import com.gengzp.permission.utils.PermissionUtils;
import com.gengzp.system.facade.IPermissionFacade;
import com.gengzp.system.facade.ISysUserFacade;
import com.gengzp.system.mapper.SysRoleMapper;
import com.gengzp.system.service.ISysRoleService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName SysRoleServiceImpl
 * @Description 系统角色模块服务层实现
 * @Author gengzp
 * @Date 2025/5/16 0:32
 */
@Service
public class SysRoleServiceImpl implements ISysRoleService {

    private static final Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ISysUserFacade sysUserFacade;

    @Autowired
    private IPermissionFacade permissionFacade;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSysRole(AddSysRoleReq req) {
        // 查询当前角色名称是否存在
        if (Objects.nonNull(sysRoleMapper.selectSysRoleByRoleName(req.getRoleName()))) {
            throw BusinessException.get("角色名称已存在");
        }

        // 保存角色到数据库
        SysRole sysRole = new SysRole();
        sysRole.setRoleName(req.getRoleName());
        sysRole.setRoleDescription(req.getRoleDescription());
        sysRoleMapper.insertSysRole(sysRole);

        // 保存角色到缓存
        PermissionUtils.assignCacheRolePermissions(sysRole.getId(), Collections.emptyList(), true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editSysRole(EditSysRoleReq req) {
        // 根据id查询角色信息
        SysRole sysRole = sysRoleMapper.selectSysRoleById(Long.valueOf(req.getRoleId()));
        if (Objects.isNull(sysRole)) {
            throw BusinessException.get("当前角色已经不存在");
        }

        // 将编辑后的角色信息落库
        sysRole.setRoleName(req.getRoleName());
        sysRole.setRoleDescription(req.getRoleDescription());
        sysRoleMapper.updateSysRoleById(sysRole);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeSysRoleById(Long roleId) {
        // 从数据库中删除角色
        sysRoleMapper.deleteSysRoleById(roleId);
        // 从数据库中删除角色和用户的关联
        permissionFacade.removeUserRoleRelationByRoleId(roleId);
        // 使用权限框架从缓存中移除角色
        PermissionUtils.removeCacheRole(roleId);
    }

    @Override
    public PaginationResult<PageSysRoleResp> pageQuerySysRole(PageSysRoleReq req) {
        List<PageSysRoleResp> result = Lists.newArrayList();

        // 从数据库中查询系统角色信息
        List<SysRole> sysRoles = sysRoleMapper.pageQuerySysRole(req);
        if (CollectionUtils.isEmpty(sysRoles)) {
            return PaginationResult.get(result, req);
        }

        // 循环填充查询结果
        for (SysRole sysRole : sysRoles) {
            PageSysRoleResp resp = new PageSysRoleResp();
            resp.setId(String.valueOf(sysRole.getId()));
            resp.setRoleName(sysRole.getRoleName());
            resp.setRoleDescription(sysRole.getRoleDescription());
            resp.setCreatedBy(String.valueOf(sysRole.getCreatedBy()));
            resp.setCreatedTime(sysRole.getCreatedTime());
            resp.setLastModifiedBy(String.valueOf(sysRole.getLastModifiedBy()));
            resp.setLastModifiedTime(sysRole.getLastModifiedTime());
            result.add(resp);
        }

        // 填充操作人昵称
        sysUserFacade.fillInEntitiesOperatorInfo(result);

        return PaginationResult.get(result, req);
    }

    @Override
    public SearchSysRoleResp searchSysRoleById(Long roleId) {
        SysRole sysRole = sysRoleMapper.selectSysRoleById(roleId);
        if (Objects.isNull(sysRole)) {
            throw BusinessException.get("当前角色已经不存在");
        }

        // 组装返回实体
        SearchSysRoleResp resp = new SearchSysRoleResp();
        resp.setId(String.valueOf(sysRole.getId()));
        resp.setRoleName(sysRole.getRoleName());
        resp.setRoleDescription(sysRole.getRoleDescription());
        resp.setCreatedBy(String.valueOf(sysRole.getCreatedBy()));
        resp.setCreatedTime(sysRole.getCreatedTime());
        resp.setLastModifiedBy(String.valueOf(sysRole.getLastModifiedBy()));
        resp.setLastModifiedTime(sysRole.getLastModifiedTime());

        // 填充操作人昵称
        sysUserFacade.fillInEntityOperatorInfo(resp);

        // 组装权限集合信息
        if (StringUtils.isNotBlank(sysRole.getPermissions())) {
            Map<String, String> permissionCode2NameMap = permissionFacade.searchPermissionCode2NameMap();
            resp.setPermissions(
                    Arrays.stream(sysRole.getPermissions().split(",")).filter(permissionCode2NameMap::containsKey)
                            .map(v -> new PermissionDto(v, permissionCode2NameMap.get(v))).collect(Collectors.toList()));
        }

        return resp;
    }

    @Override
    public List<String> searchPermissionsByRoleIds(Collection<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }

        List<String> permissions = sysRoleMapper.selectPermissionsByIds(Lists.newArrayList(roleIds));
        if (CollectionUtils.isEmpty(permissions)) {
            return Collections.emptyList();
        }

        return permissions.stream().map(v -> v.split(","))
                .flatMap(Arrays::stream).distinct().collect(Collectors.toList());
    }

    @Override
    public SearchSysRolePermissionsResp searchSysRolePermissionsById(Long roleId) {
        SearchSysRolePermissionsResp result = new SearchSysRolePermissionsResp();
        result.setPermissionNames(Lists.newArrayList());

        // 查询当前用户拥有的权限编码集合
        List<String> permissionCodes = sysRoleMapper.selectPermissionsByIds(List.of(roleId));
        if (CollectionUtils.isEmpty(permissionCodes)) {
            return result;
        }
        permissionCodes = permissionCodes.stream().filter(Objects::nonNull).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(permissionCodes)) {
            return result;
        }

        // 因为roleId 只有一个，所以permissionCodes只有一个元素，所以直接取第一个元素
        permissionCodes = Arrays.asList(permissionCodes.get(0).split(","));

        // 将权限编码转为权限名称
        result.setPermissionNames(
                permissionCodes.stream().map(PermissionEnum::getNameByCode).collect(Collectors.toList())
        );

        // 将权限保存到权限框架缓存
        List<String> finalPermissionCodes = permissionCodes;
        ExecutorUtils.getThreadPool().execute(() ->
                PermissionUtils.assignCacheRolePermissions(roleId, finalPermissionCodes, true));

        return result;
    }

}
